home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / shade.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  10KB  |  481 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    shade -
  19.  *        Support for describing materials and light sources by 
  20.  *    text files.
  21.  *
  22.  *            Paul Haebetli - 1988
  23.  */
  24. #include "shade.h"
  25. #include "stdio.h"
  26. #include "gl.h"
  27. #include "lum.h"
  28.  
  29. material *newmat()
  30. {
  31.     return (material *)mymalloc(sizeof(material)); 
  32. }
  33.  
  34. freemat(mat)
  35. material *mat;
  36. {
  37.     free(mat);
  38. }
  39.  
  40. material *matfromfile(name)
  41. char *name;
  42. {
  43.     char fullname[100];
  44.     material *mat;
  45.     FILE *f;
  46.  
  47.     findname(name,fullname,"GFXPATH");
  48.     f = fopen(fullname,"r");
  49.     if(!f) {
  50.     fprintf(stderr,"matfromfile: can't open file %s\n",fullname);
  51.     exit(1);
  52.     }
  53.     mat = matfromf(f);
  54.     fclose(f);
  55.     return mat;
  56. }
  57.  
  58. material *matfromf(f)
  59. FILE *f;
  60. {
  61.     material *mat;
  62.     char token[256];
  63.     float r, g, b;
  64.  
  65.     mat = newmat();
  66.     if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4) 
  67.     goto materror;
  68.     if(strcmp(token,"emission") != 0) 
  69.     goto materror;
  70.     mat->emission.x = r;
  71.     mat->emission.y = g;
  72.     mat->emission.z = b;
  73.  
  74.     if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4) 
  75.     goto materror;
  76.     if(strcmp(token,"ambient") != 0) 
  77.     goto materror;
  78.     mat->ambient.x = r;
  79.     mat->ambient.y = g;
  80.     mat->ambient.z = b;
  81.  
  82.     if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4) 
  83.     goto materror;
  84.     if(strcmp(token,"diffuse") != 0) 
  85.     goto materror;
  86.     mat->diffuse.x = r;
  87.     mat->diffuse.y = g;
  88.     mat->diffuse.z = b;
  89.  
  90.     if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4) 
  91.     goto materror;
  92.     if(strcmp(token,"specular") != 0) 
  93.     goto materror;
  94.     mat->specular.x = r;
  95.     mat->specular.y = g;
  96.     mat->specular.z = b;
  97.  
  98.     if(fscanf(f,"%s %f",token,&r) != 2) 
  99.     goto materror;
  100.     if(strcmp(token,"shininess") != 0) 
  101.     goto materror;
  102.     mat->shininess = r;
  103.  
  104.     if(fscanf(f,"%s %f",token,&r) != 2) 
  105.     goto materror;
  106.     if(strcmp(token,"alpha") != 0) 
  107.     goto materror;
  108.     mat->alpha = r;
  109.     return mat;
  110.  
  111. materror:
  112.     freemat(mat);
  113.     return 0;
  114. }
  115.  
  116. mattofile(name,mat)
  117. char *name;
  118. material *mat;
  119. {
  120.     FILE *f;
  121.     f = fopen(name,"w");
  122.     if(!f) {
  123.     fprintf(stderr,"mattofile: can't open file %s\n",name);
  124.     exit(1);
  125.     }
  126.     mattof(f,mat);
  127.     fclose(f);
  128. }
  129.  
  130. mattof(f,mat)
  131. FILE *f;
  132. material *mat;
  133. {
  134.  
  135.     fprintf(f,"emission %f %f %f\n", 
  136.             mat->emission.x,mat->emission.y,mat->emission.z);
  137.     fprintf(f,"ambient %f %f %f\n", 
  138.             mat->ambient.x,mat->ambient.y,mat->ambient.z);
  139.     fprintf(f,"diffuse %f %f %f\n", 
  140.             mat->diffuse.x,mat->diffuse.y,mat->diffuse.z);
  141.     fprintf(f,"specular %f %f %f\n", 
  142.             mat->specular.x,mat->specular.y,mat->specular.z);
  143.     fprintf(f,"shininess %f\n", mat->shininess);
  144.     fprintf(f,"alpha %f\n", mat->alpha);
  145. }
  146.  
  147. matlerp(m0,m1,m,p)
  148. material *m0, *m1, *m;
  149. float p;
  150. {
  151.     vlerp(&m0->emission,&m1->emission,&m->emission,p);
  152.     vlerp(&m0->ambient,&m1->ambient,&m->ambient,p);
  153.     vlerp(&m0->diffuse,&m1->diffuse,&m->diffuse,p);
  154.     vlerp(&m0->specular,&m1->specular,&m->specular,p);
  155.     m->shininess = flerp(m0->shininess,m1->shininess,p); 
  156. }
  157.  
  158. matprint(mat)
  159. material *mat;
  160. {
  161.     mattofile("/dev/tty",mat);
  162. }
  163.  
  164.  
  165. lamp *newlamp()
  166. {
  167.     lamp *la;
  168.  
  169.     la = (lamp *)mymalloc(sizeof(lamp)); 
  170.     la->next = 0;
  171.     return la;
  172. }
  173.  
  174. freelamp(l)
  175. lamp *l;
  176. {
  177.     free(l);
  178. }
  179.  
  180. lights *newlights()
  181. {
  182.     lights *l;
  183.  
  184.     l =  (lights *)mymalloc(sizeof(lights)); 
  185.     l->lamps = 0;
  186.     return l;
  187. }
  188.  
  189. freelights(li)
  190. lights *li;
  191. {
  192.     lamp *l, *nl;
  193.  
  194.     l = li->lamps;
  195.     while(l) {
  196.     nl = l->next;
  197.     freelamp(l);
  198.     l = nl;
  199.     }
  200.     free(li);
  201. }
  202.  
  203. lights *lightsfromfile(name)
  204. char *name;
  205. {
  206.     char fullname[100];
  207.     FILE *f;
  208.     lights *li;
  209.  
  210.     findname(name,fullname,"GFXPATH");
  211.     f = fopen(fullname,"r");
  212.     if(!f) {
  213.     fprintf(stderr,"lightsfromfile: can't open file %s\n",fullname);
  214.     exit(1);
  215.     }
  216.     li = lightsfromf(f);
  217.     fclose(f);
  218.     return li;
  219. }
  220.  
  221. lights *lightsfromf(f)
  222. FILE *f;
  223. {
  224.     lights *li;
  225.     lamp *la, *lastla;
  226.     char token[256];
  227.     float r, g, b, w;
  228.     int flag;
  229.  
  230.     li = newlights();
  231.     la = 0;
  232.     if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4) 
  233.     goto lightserror;
  234.     if(strcmp(token,"ambient") != 0) 
  235.     goto lightserror;
  236.     li->ambient.x = r;
  237.     li->ambient.y = g;
  238.     li->ambient.z = b;
  239.  
  240.     if(fscanf(f,"%s %d",token,&flag) != 2) 
  241.     goto lightserror;
  242.     if(strcmp(token,"localviewer") != 0) 
  243.     goto lightserror;
  244.     li->localviewer = flag;
  245.  
  246.     if(fscanf(f,"%s %f",token,&r) != 2) 
  247.     goto lightserror;
  248.     if(strcmp(token,"attenconst") != 0) 
  249.     goto lightserror;
  250.     li->attenconst = r;
  251.  
  252.     if(fscanf(f,"%s %f",token,&r) != 2) 
  253.     goto lightserror;
  254.     if(strcmp(token,"attenmult") != 0) 
  255.     goto lightserror;
  256.     li->attenmult = r;
  257.  
  258.     lastla = 0;
  259.     while(1) {
  260.     if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4) 
  261.         break;
  262.     if(strcmp(token,"ambient") != 0) 
  263.         goto lightserror;
  264.     la = newlamp();
  265.     la->ambient.x =  r;
  266.     la->ambient.y =  g;
  267.     la->ambient.z =  b;
  268.  
  269.     if(fscanf(f,"%s %f %f %f",token,&r,&g,&b) != 4) 
  270.         break;
  271.     if(strcmp(token,"color") != 0) 
  272.         goto lightserror;
  273.     la->color.x =  r;
  274.     la->color.y =  g;
  275.     la->color.z =  b;
  276.  
  277.     if(fscanf(f,"%s %f %f %f %f",token,&r,&g,&b,&w) != 5) 
  278.         break;
  279.     if(strcmp(token,"position") != 0) 
  280.         goto lightserror;
  281.     la->position.x =  r;
  282.     la->position.y =  g;
  283.     la->position.z =  b;
  284.     la->position.w =  w;
  285.     if(!lastla) {
  286.         li->lamps = la;
  287.         lastla = la;
  288.     } else {
  289.         lastla->next = la;
  290.         lastla = la;
  291.     }
  292.     }
  293.     return li;
  294.  
  295. lightserror:
  296.     if(la)
  297.     freelamp(la);
  298.     freelights(li);
  299.     return 0;
  300. }
  301.  
  302. lightstofile(name,li)
  303. char *name;
  304. lights *li;
  305. {
  306.     FILE *f;
  307.     lamp *la;
  308.  
  309.     f = fopen(name,"w");
  310.     if(!f) {
  311.     fprintf(stderr,"lightstofile: can't open file %s\n",name);
  312.     exit(1);
  313.     }
  314.     lightstof(f,li);
  315.     fclose(f);
  316. }
  317.  
  318. lightstof(f,li)
  319. FILE *f;
  320. lights *li;
  321. {
  322.     lamp *la;
  323.  
  324.     fprintf(f,"ambient %g %g %g\n", 
  325.             li->ambient.x,li->ambient.y,li->ambient.z);
  326.     fprintf(f,"localviewer %d\n",li->localviewer);
  327.     fprintf(f,"attenconst %g\n",li->attenconst);
  328.     fprintf(f,"attenmult %g\n",li->attenmult);
  329.     la = li->lamps;
  330.     while(la) {
  331.     fprintf(f,"ambient %f %f %f\n",
  332.         la->ambient.x,la->ambient.y,la->ambient.z);
  333.     fprintf(f,"color %f %f %f\n",
  334.         la->color.x,la->color.y,la->color.z);
  335.     fprintf(f,"position %f %f %f %f\n",
  336.         la->position.x,la->position.y,la->position.z,la->position.w);
  337.     la = la->next;
  338.     }
  339. }
  340.  
  341. materialname(name)
  342. char *name;
  343. {
  344.     material *mat;
  345.  
  346.     mat = matfromfile(name);
  347.     if(!mat)
  348.     return;
  349.     setmaterial(mat);
  350.     freemat(mat);
  351. }
  352.  
  353. setmaterial(mat)
  354. material *mat;
  355. {
  356.     float mat_desc[40];
  357.  
  358.     if(!mat) {
  359.     fprintf(stderr,"setmaterial: null material\n");
  360.     return;
  361.     }
  362.     mat_desc[0] = EMISSION;
  363.     mat_desc[1] = mat->emission.x;
  364.     mat_desc[2] = mat->emission.y;
  365.     mat_desc[3] = mat->emission.z;
  366.     mat_desc[4] = AMBIENT;
  367.     mat_desc[5] = mat->ambient.x;
  368.     mat_desc[6] = mat->ambient.y;
  369.     mat_desc[7] = mat->ambient.z;
  370.     mat_desc[8] = DIFFUSE;
  371.     mat_desc[9] = mat->diffuse.x;
  372.     mat_desc[10] = mat->diffuse.y;
  373.     mat_desc[11] = mat->diffuse.z;
  374.     mat_desc[12] = SPECULAR;
  375.     mat_desc[13] = mat->specular.x;
  376.     mat_desc[14] = mat->specular.y;
  377.     mat_desc[15] = mat->specular.z;
  378.     mat_desc[16] = SHININESS;
  379.     mat_desc[17] = mat->shininess;
  380.     mat_desc[18] = LMNULL;
  381.     mat_desc[18] = ALPHA;
  382.     mat_desc[19] = mat->alpha;
  383.     mat_desc[20] = LMNULL;
  384.     lmdef(DEFMATERIAL, 1, 21, mat_desc);
  385.     lmbind(MATERIAL, 1);
  386. }
  387.  
  388. shadingoff()
  389. {
  390.     lmbind(LMODEL,0);
  391. }
  392.  
  393. shadingon()
  394. {
  395.     lmbind(LMODEL,1);
  396. }
  397.  
  398. lightsname(name)
  399. char *name;
  400. {
  401.     lights *li;
  402.  
  403.     li = lightsfromfile(name);
  404.     if(!li)
  405.     return;
  406.     setlights(li);
  407.     freelights(li);
  408. }
  409.  
  410. setlights(li)
  411. lights *li;
  412. {
  413.     float li_desc[40];
  414.     lamp *la;
  415.     int i;
  416.  
  417.     if(!li) {
  418.     fprintf(stderr,"setlight: null light\n");
  419.     return;
  420.     }
  421.     li_desc[0] = AMBIENT;
  422.     li_desc[1] = li->ambient.x;
  423.     li_desc[2] = li->ambient.y;
  424.     li_desc[3] = li->ambient.z;
  425.     li_desc[4] = LOCALVIEWER;
  426.     li_desc[5] = li->localviewer;
  427.     li_desc[6] = ATTENUATION;
  428.     li_desc[7] = li->attenconst;
  429.     li_desc[8] = li->attenmult;
  430.     li_desc[9] = LMNULL;
  431.     lmdef(DEFLMODEL, 1, 10, li_desc);
  432.     lmbind(LMODEL, 1);
  433.     la = li->lamps;
  434.     for(i=1; i<=8; i++) {
  435.     if(!la) {
  436.         lmbind(LIGHT0+i-1, 0);
  437.         } else {
  438.         li_desc[0] = AMBIENT;
  439.         li_desc[1] = la->ambient.x;
  440.         li_desc[2] = la->ambient.y;
  441.         li_desc[3] = la->ambient.z;
  442.         li_desc[4] = LCOLOR;
  443.         li_desc[5] = la->color.x;
  444.         li_desc[6] = la->color.y;
  445.         li_desc[7] = la->color.z;
  446.         li_desc[8] = POSITION;
  447.         li_desc[9] = la->position.x;
  448.         li_desc[10] = la->position.y;
  449.         li_desc[11] = la->position.z;
  450.         li_desc[12] = la->position.w;
  451.         li_desc[13] = LMNULL;
  452.         lmdef(DEFLIGHT, i, 14, li_desc);
  453.             lmbind(LIGHT0+i-1, i);
  454.         la = la->next;
  455.     }
  456.     }
  457. }
  458.  
  459. static int bwflag;
  460.  
  461. bwmode(b)
  462. int b;
  463. {
  464.     bwflag = b;
  465. }
  466.  
  467. diffusergb(r,g,b)
  468. float r, g, b;
  469. {
  470.     float mat_desc[40];
  471.  
  472.     if(bwflag) 
  473.     r = g = b = LUM(r,g,b);
  474.     mat_desc[0] = DIFFUSE;
  475.     mat_desc[1] = r;
  476.     mat_desc[2] = g;
  477.     mat_desc[3] = b;
  478.     mat_desc[4] = LMNULL;
  479.     lmdef(DEFMATERIAL, 1, 5, mat_desc);
  480. }
  481.